package com.woniu.stafforder.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.woniu.stafforder.entity.Order;
import com.woniu.stafforder.entity.dto.OrderEchartsCountDTO;
import com.woniu.stafforder.entity.dto.OrderEchartsDTO;
import com.woniu.stafforder.entity.dto.OrderMonitorCountDto;
import com.woniu.stafforder.es.OrderES;
import com.woniu.stafforder.es.OrderEchartsES;
import com.woniu.stafforder.mapper.OrderMapper;
import com.woniu.stafforder.service.CustomService;
import com.woniu.stafforder.service.OrderService;
import lombok.SneakyThrows;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedTopHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Service
public class CustomServiceImpl implements CustomService {
    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private OrderES orderES;
    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderEchartsES orderEchartsES;

    @Override
    public List<OrderMonitorCountDto> countOrdersByProvinceAndSourceId() {
        List<OrderMonitorCountDto> results = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest("zgyd");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.size(0);

        sourceBuilder.query(QueryBuilders.termQuery("status", 4));

        TermsAggregationBuilder provinceAggregation = AggregationBuilders.terms("byProvince")
                .field("province.keyword")
                .size(100000); // 展示的省份数量，根据需要调整

        TermsAggregationBuilder sourceIdAggregation = AggregationBuilders.terms("bySourceId")
                .field("sourceId")
                .size(100000); // 展示的source_id数量

        sourceIdAggregation.subAggregation(AggregationBuilders.count("count").field("_id"));

        provinceAggregation.subAggregation(sourceIdAggregation);
        sourceBuilder.aggregation(provinceAggregation);
        searchRequest.source(sourceBuilder);

        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

            Terms provinces = searchResponse.getAggregations().get("byProvince");
            for (Terms.Bucket province : provinces.getBuckets()) {
                String provinceName = province.getKeyAsString();

                Terms sourceIds = province.getAggregations().get("bySourceId");
                for (Terms.Bucket sourceId : sourceIds.getBuckets()) {
//                    转换为Integer类型
                    Integer sourceIdValue = ((ParsedLongTerms.ParsedBucket) sourceId).getKeyAsNumber().intValue();
                    Long count = sourceId.getDocCount();

                    results.add(new OrderMonitorCountDto(sourceIdValue,provinceName, count));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return results;
    }

    @Override
    public void saveZgyd() {
        List<Order> list = orderService.query().list();
        Iterable<Order> all = orderES.findAll();

        Set<Order> existingOrderSet = new HashSet<>();
        all.forEach(existingOrderSet::add);


        List<Order> nonDuplicateOrders = list.stream()
                .filter(order -> !existingOrderSet.contains(order))
                .collect(Collectors.toList());

        // 保存不重复的订单
        if (!nonDuplicateOrders.isEmpty()) {
            orderES.saveAll(nonDuplicateOrders);
        }
    }

    @SneakyThrows
    @Override
    public List<OrderEchartsCountDTO> countSoruceInfo(Integer sourceId,Date startTime,Date endTime) {
        List<OrderEchartsCountDTO> result = new ArrayList<>();

        SearchRequest searchRequest = new SearchRequest("zgyde");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("sourceId", sourceId));
        boolQueryBuilder.must(QueryBuilders.termQuery("status", 4));

        if (startTime != null && endTime != null) {
            long startMillis = startTime.getTime();
            long time = endTime.getTime();
            RangeQueryBuilder createTimeRangeQuery = QueryBuilders.rangeQuery("createTime")
                    .gte(startMillis)
                    .lt(time);
            boolQueryBuilder.filter(createTimeRangeQuery);
        }

        searchSourceBuilder.query(boolQueryBuilder);

        TermsAggregationBuilder termsAgg = AggregationBuilders.terms("serviceAgg").field("serviceName.keyword");
        termsAgg.subAggregation(AggregationBuilders.terms("orderTypeAgg").field("orderTypeName.keyword"));
        searchSourceBuilder.aggregation(termsAgg);

        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            Terms serviceTerms = searchResponse.getAggregations().get("serviceAgg");
            for (Terms.Bucket serviceBucket : serviceTerms.getBuckets()) {
                String serviceName = serviceBucket.getKeyAsString();
                Terms orderTypeTerms = serviceBucket.getAggregations().get("orderTypeAgg");
                for (Terms.Bucket orderTypeBucket : orderTypeTerms.getBuckets()) {
                    String orderTypeName = orderTypeBucket.getKeyAsString();
                    long docCount = orderTypeBucket.getDocCount();
                    result.add(new OrderEchartsCountDTO(sourceId, orderTypeName, docCount, serviceName));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }
    //    保存不重复的数据
    @Override
    public void saveSourceList() {
        Iterable<OrderEchartsDTO> allEsData = orderEchartsES.findAll();
        List<OrderEchartsDTO> dbData = orderMapper.querySourceInfo();
        Map<Long, OrderEchartsDTO> esDataMap =
                StreamSupport.stream(allEsData.spliterator(), false)
                        .collect(Collectors.toMap(OrderEchartsDTO::getId, Function.identity()));
        List<OrderEchartsDTO> dataToUpdate = dbData.stream()
                .filter(dbRecord -> {
                    OrderEchartsDTO esRecord = esDataMap.get(dbRecord.getId());
                    return esRecord == null || !esRecord.equals(dbRecord);
                })
                .collect(Collectors.toList());

        if (!dataToUpdate.isEmpty()) {
            orderEchartsES.saveAll(dataToUpdate);
        }
    }}
